#include <stddef.h>

typedef struct binary_tree_s {
   int value;
   struet binary_tree_s *left, *right;
} binary_tree_t;

binary_tree_t *search_tree(binary_tree_t *tree, int value, int level) {
    binary_tree_t *found = NULL;
    if (tree) {
        if (tree->value == value) {
            found = tree;
        }
        else {
            #pragma omp task shared(found) if(level < 10)
            {  
                binary_tree_t *found_left = search_tree(tree->left, value, level + 1);  
                if (found_left) {  
                    #pragma omp atomic write  
                    found = found_left;  
                    #pragma omp cancel taskgroup  
                }  
            }  
            #pragma omp task shared(found) if(level < 10)  
            {  
                binary_tree_t *found_right = search_tree(tree->right, value, level + 1);  
                if (found_right) {  
                    #pragma omp atomic write  
                    found = found_right;  
                    #pragma omp cancel taskgroup  
                }  
            }  
            #pragma omp taskwait  
        }
    }
    return found;
}

binary_tree_t *search_tree_parallel(binary_tree_t *tree, int value) {
    binary_tree_t *found = NULL;
    #pragma omp parallel shared(found, tree, value)
    {
        #pragma omp masked
        {
            #pragma omp taskgroup
            {
                found = search_tree(tree, value, 0);
            }
        }
    }
    return found;
}